﻿using System;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;

namespace BanditGame
{
    public class Guardian
    {
        public Guardian(int X, int Y)
        {
            PositionX = X;
            PositionY = Y;
        }

        /// <summary>
        /// Guardians horizontal position
        /// </summary>
        public int PositionX { get; set; }

        /// <summary>
        /// Guardians vertical position
        /// </summary>
        public int PositionY { get; set; }

        /// <summary>
        /// Guardians type - 4 levels of difficulty
        /// </summary>
        public int Type { get; set; }
        
        /// <summary>
        /// Checks visibility between player and guardian
        /// </summary>
        /// <param name="playerX"></param>
        /// <param name="playerY"></param>
        /// <param name="currentLevel"></param>
        /// <returns>returns true if there is no wall between player an guardian</returns>
        public Boolean checkVisibility(int playerX, int playerY, Level currentLevel)
        {
            // Kontrolujeme zda na usecce mezi hracem a strazcem je zed
            // Mějme úsečky "a", "b" definované dvěma body (začátky "a1", "b1" a konce "a2", "b2"). 
            //Chceme zjistit bod, kde se protínají. Nejdřív najdeme průsečík přímek a, b. Aby to byl průsečík úseček, 
            //musí ležet mezi začátky a konci obou úseček. 
            // Při výpočtu průsečíku si přímku převedeme do směrnicového tvaru y=f×x+g, kde "f" je směrnice a "g" je svislý posun.
 
            //prusecik
            //double[] intersection = new double[2];
            double intersectionX;
            double intersectionY;
            //primka bude mezi stredem hrace a stredem strazce
            double playerMiddleX = ((playerX * Defaults.CellSizeInPixel) + (Defaults.CellSizeInPixel / 2));
            double playerMiddleY = ((playerY * Defaults.CellSizeInPixel) + (Defaults.CellSizeInPixel / 2));
            double guardianMiddleX = ((PositionX * Defaults.CellSizeInPixel)) + ((Defaults.CellSizeInPixel / 2));
            double guardianMiddleY = ((PositionY * Defaults.CellSizeInPixel)) + ((Defaults.CellSizeInPixel / 2));
            
            //overime uklopricky kazdeho policka zdi zda se neprotinaji s primkou
            foreach (var cell in currentLevel.CellList)
            {
                if (cell.CellType == '#')
                {
                    //omezeni kontroly jen na policka jen na oblast mezi hracem a strazcem.
                    if (cell.PositionX >= Math.Min(playerX, PositionX) &&
                        cell.PositionX <= Math.Max(playerX, PositionX) &&
                        cell.PositionY >= Math.Min(playerY, PositionY) &&
                        cell.PositionY <= Math.Max(playerY, PositionY))
                    {
                        double[] x1 = new double[2];
                        double[] y1 = new double[2];
                        double[] x2 = new double[2];
                        double[] y2 = new double[2];

                        x1[0] = cell.PositionX*Defaults.CellSizeInPixel;
                        y1[0] = cell.PositionY*Defaults.CellSizeInPixel;
                        x2[0] = cell.PositionX*Defaults.CellSizeInPixel + Defaults.CellSizeInPixel;
                        y2[0] = cell.PositionY*Defaults.CellSizeInPixel + Defaults.CellSizeInPixel;

                        x1[1] = cell.PositionX*Defaults.CellSizeInPixel;
                        y1[1] = cell.PositionY*Defaults.CellSizeInPixel + Defaults.CellSizeInPixel;
                        x2[1] = cell.PositionX*Defaults.CellSizeInPixel + Defaults.CellSizeInPixel;
                        y2[1] = cell.PositionY*Defaults.CellSizeInPixel;

                        for (int i = 0; i < 2; i++)
                        {
                            double f1 = -(guardianMiddleY - playerMiddleY)/(playerMiddleX - guardianMiddleX);
                            double f2 = -(y2[i] - y1[i])/(x1[i] - x2[i]);
                            double g1 = playerMiddleY - f1*playerMiddleX;
                            double g2 = y1[i] - f2*x1[i];

                            if (playerMiddleX == guardianMiddleX)
                            {
                                intersectionX = playerMiddleX;
                                intersectionY = f2*playerX + g2;
                            }
                            else if (x1 == x2)
                            {
                                intersectionX = x1[i];
                                intersectionY = f1*x1[i] + g1;
                            }
                            else
                            {
                                intersectionX = (g2 - g1)/(f1 - f2);
                                intersectionY = f1*intersectionX + g1;
                            }


                            if (
                                isInRect(intersectionX, intersectionY, playerMiddleX, playerMiddleY, guardianMiddleX,
                                         guardianMiddleY) &&
                                isInRect(intersectionX, intersectionY, x1[i], y1[i], x2[i], y2[i]))
                            {
                                return false;
                                //intersection[0] = intersectionX;
                                //intersection[1] = intersectionY;
                                //return intersection;
                            }
                        }
                    }
                }
            }
            //intersection[0] = 0;
            //intersection[1] = 0;
            //return intersection;
            return true;
        }
 
        public static Boolean isInRect(double pX, double pY, double x1, double y1, double x2, double y2)
        {
           if(pX >= Math.Min(x1, x2) && pX <= Math.Max(x1, x2) && pY >= Math.Min(y1, y2) && pY <= Math.Max(y1, y2)) 
               return true;
           return false;
        }        
    }





        //private int _moveX = 0;
        //private int _moveY = 0;
        
        

        //// * Methods for moving on gamefield, 
        ////   called when keyboard arrows are pressed
        //public void moveRight()
        //{
        //    _moveX = 1;
        //    _moveY = 0;
        //    //updatePosition(this.moveX, this.moveY);
        //}
        //public void moveLeft()
        //{
        //    _moveX = -1;
        //    _moveY = 0;
        //    //updatePosition(this.moveX, this.moveY);
        //}
        //public void moveUp()
        //{
        //    _moveX = 0;
        //    _moveY = -1;
        //    //updatePosition(this.moveX, this.moveY);
        //}

        //public void moveDown()
        //{
        //    _moveX = 0;
        //    _moveY = 1;
        //    //updatePosition(this.moveX, this.moveY);
        //}

        //// Updates position of bandit
        //public void updatePosition()
        //{
        //    PositionX += _moveX;
        //    PositionY += _moveY;
        //}

        ////Collision Checking
        //public bool CheckForCollision(Level currentLevel)
        //{

        //    bool collision = false;

        //    //Checking for collisions with borders of canvas (in case someone forget make wall)
        //    if ((PositionX + _moveX) < 0)
        //    {
        //        _moveX = 0;   /* left border */
        //        return collision;
        //    }
        //    if ((PositionY + _moveY) < 0)
        //    {
        //        _moveY = 0;   /* top border */
        //        return collision;
        //    }

        //    /******************************************************************************************************************************************************************************************************************/
        //    if ((PositionX + _moveX) > currentLevel.SizeX)//Defaults.MaxGameFieldWidth) // Settings.gameFieldWidth)
        //    {
        //        //this.positionX = Settings.gameFieldWidth;    /* bottom border */
        //        _moveX = 0; /* left border */
        //        return collision;
        //    }
        //    /******************************************************************************************************************************************************************************************************************/
        //    if ((this.PositionY + this._moveY) > currentLevel.SizeY)//Defaults.MaxGameFieldHeight) //Settings.gameFieldHeight)
        //    {
        //        //this.positionY = Settings.gameFieldHeight;   /* right border */
        //        _moveY = 0;   /* top border */
        //        return collision;
        //    }

        //    Cell nextCell =
        //        currentLevel.CellList.Where
        //        (x => x.PositionX == (this.PositionX + _moveX)).Where(y => y.PositionY ==
        //            (this.PositionY + this._moveY)).FirstOrDefault();

        //    //Checking collisions with wall
        //    if (nextCell.CellType == '#')
        //    {
        //        collision = true;
        //    }

        //    //Checking collisions with question
        //    if (nextCell.CellType == '?')
        //    {
        //        QuestionWindows questWin = new QuestionWindows();
        //        questWin.Show();
        //    }


        //    return collision;

        //}
   // }
    
}
